Title: How to Add an Email Filter to WooCommerce Orders

Publish Date: Fri, 27 Oct 2023 08:19:57 +0000

Categories: Uncategorized

Content:

Working with WooCommerce, sometimes there are small tweaks that can enhance our experience, making administrative tasks simpler. One such enhancement I've recently explored is adding an email filter directly within the Orders page of WooCommerce. This is especially useful if you want to quickly hide all orders associated with a specific email.









What We Are Doing to Do



We will add a text input to the WooCommerce Orders page where you can type in an email address, or multiple ones separated by comma. Once submitted, the page will filter and hide any orders from that specific email.



A Little Bit of Code



First, we introduce the email input on the Orders page. This is achieved by the add_email_filter function, which checks if we're on the shop_order page and then displays the email input field:



/**
 * @snippet       Add Email Filter Field
 * @author        Nicola Mustone
 * @author_url    https://nicolamustone.blog/2023/10/27/how-to-add-an-email-filter-to-woocommerce-orders/
 * @tested-up-to  WooCommerce 8.4.X
 */
function nm_add_email_filter() {
    global $typenow;
    
    if ( 'shop_order' == $typenow ) {
        $current_emails = isset( $_GET['filter_emails'] ) ? sanitize_text_field( $_GET['filter_emails'] ) : '';
        echo '<input type="text" name="filter_emails" placeholder="Hide orders by email" value="' . esc_attr( $current_emails ) . '">';
    }
}
add_action( 'restrict_manage_posts', 'nm_add_email_filter' );



Next, once an email is provided, the system needs to fetch the relevant orders. This is where filter_orders_by_emails comes in. It listens for the email input, splits it into multiple emails if it's separated by comma, and retrieves all orders that DO NOT include those email addresses:



/**
 * @snippet       Filter Orders by Email
 * @author        Nicola Mustone
 * @author_url    https://nicolamustone.blog/2023/10/27/how-to-add-an-email-filter-to-woocommerce-orders/
 * @tested-up-to  WooCommerce 8.4.X
 */
function nm_filter_orders_by_emails( $query ) {
    global $typenow, $wpdb;
    
    if ( 'shop_order' == $typenow && isset( $_GET['filter_emails'] ) && !empty( $_GET['filter_emails'] ) ) {
        $emails = array_map('sanitize_email', explode(',', $_GET['filter_emails']));

        $order_ids = $wpdb->get_col( "SELECT pm.post_id FROM {$wpdb->postmeta} pm WHERE pm.meta_key = '_billing_email' AND pm.meta_value IN ('" . join("','", $emails) . "')" );

        // Adjust the main query to exclude orders with the specified email
        $query->set( 'post__not_in', $order_ids );
    }
}
add_action( 'pre_get_posts', 'nm_filter_orders_by_emails' );



Hide Orders From Pre-Defined Email Addresses



If your goal is instead to hide orders from a pre-defined email address, the code is slightly different, but as simple as the one above. This could be useful if you have, for example, a Point of Sale connected to WooCommerce that would generate lots of orders on the website:



/**
 * @snippet       Show/Hide Orders by Specific Email Address
 * @author        Nicola Mustone
 * @author_url    https://nicolamustone.blog/2023/10/27/how-to-add-an-email-filter-to-woocommerce-orders/
 * @tested-up-to  WooCommerce 8.4.X
 */

define('HIDDEN_EMAIL_ORDERS', 'email@tohide.com');

function nm_add_email_filter_checkbox() {
    global $typenow;
    
    if ( 'shop_order' == $typenow ) {
        $is_checked = isset( $_GET['hide_specific_email'] ) ? 'checked' : '';
        echo '<label style="margin-right:10px;margin-left:10px;"><input style="height:1rem;" type="checkbox" name="hide_specific_email" value="1" ' . $is_checked . '> Hide orders from ' . HIDDEN_EMAIL_ORDERS . '</label>';
    }
}
add_action( 'restrict_manage_posts', 'nm_add_email_filter_checkbox' );

function nm_add_email_filter_checkbox( $query ) {
    global $typenow, $wpdb;
    
    if ( 'shop_order' == $typenow && isset( $_GET['hide_specific_email'] ) && '1' == $_GET['hide_specific_email'] ) {
        $order_ids = $wpdb->get_col( $wpdb->prepare(
            "SELECT pm.post_id FROM {$wpdb->postmeta} pm WHERE pm.meta_key = '_billing_email' AND pm.meta_value = %s",
            HIDDEN_EMAIL_ORDERS
        ) );

        // Adjust the main query to exclude orders with the specified email
        $query->set( 'post__not_in', $order_ids );
    }
}
add_action( 'pre_get_posts', 'nm_add_email_filter_checkbox' );



Conclusion



Simple, yet effective! By integrating this into your WooCommerce setup, you'll be able to seamlessly filter orders by email for registered and unregistered customers, streamlining your administrative tasks. As always, if you have any questions or encounter issues, feel free to share in the comments. Happy WooCommerce-ing!
